﻿using System.Collections.Generic;
using System.Linq;
using ActivateYourGlutes.Data;
using ActivateYourGlutes.Infrastructure.MembershipServices;
using ActivateYourGlutes.Services.Model;
using AutoMapper;

namespace ActivateYourGlutes.Services.Implementation
{
    public class ErrorLogProvider : MembershipProviderBase<Data.Model.ErrorLog>, IErrorLogProvider
    {
        public ErrorLogProvider(IEntityModelFactory factory, IMembershipService service) : base(factory, service)
        {
        }

        #region Implementation of IErrorLogProvider

        /// <summary>
        /// Returns a subset of errors in the error log after checking that the accessing user has rights to do so
        /// </summary>
        public IEnumerable<Error> LogItems(Account accessingAccount, int offset, int pageSize)
        {
            AuthorizeAccountAsAdministrator(accessingAccount);
            var errors =Repository.Entities.
                OrderByDescending(e => e.Date).
                Skip(offset).
                Take(pageSize).
                ToList();
            var mappedErrors = Mapper.Map<IEnumerable<Data.Model.ErrorLog>, IEnumerable<Error>>(errors);
            return mappedErrors;
        }

        /// <summary>
        /// Returns the total number of items in the error log
        /// </summary>
        public int TotalLogItems()
        {
            return Repository.Entities.Count();
        }

        /// <summary>
        /// Clears the error log
        /// </summary>
        public void Clear(Account deletingAccount)
        {
            AuthorizeAccountAsAdministrator(deletingAccount);
            // I hope this is resolved in EF4 - no delete all in EF1
            var itemsToDelete = Repository.Entities.ToList();
            //while (itemsToDelete.Any())
            //    Db.DeleteObject(itemsToDelete.First());
            foreach(var item in itemsToDelete)
                Repository.Delete(item);
            Repository.SaveChanges();
        }

        /// <summary>
        /// Deletes the specified error log item
        /// </summary>
        public void Delete(Account deletingAccount, int errorLogItemId)
        {
            AuthorizeAccountAsAdministrator(deletingAccount);
            var error = Repository.Entities.Where(logitem => logitem.Id == errorLogItemId).FirstOrDefault();
            if (error != null)
            {
                Repository.Delete(error);
                Repository.SaveChanges();
            }
        }

        /// <summary>
        /// Return a single error log item by ID
        /// </summary>
        public Error GetLogItemById(Account accessingAccount, int id)
        {
            AuthorizeAccountAsAdministrator(accessingAccount);
            var error = Repository.Entities.Where(logitem => logitem.Id == id).First();
            return Mapper.Map<Data.Model.ErrorLog, Error>(error);
        }

        #endregion
    }
}
